src: manually implement SysrootDeployTreeOpts
authorFelix Krull <f_krull@gmx.de>
Sun, 18 Oct 2020 11:21:53 +0000 (13:21 +0200)
committerColin Walters <walters@verbum.org>
Fri, 6 May 2022 16:53:56 +0000 (12:53 -0400)
rust-bindings/rust/conf/ostree.toml
rust-bindings/rust/src/auto/sysroot.rs
rust-bindings/rust/src/auto/versions.txt
rust-bindings/rust/src/lib.rs
rust-bindings/rust/src/sysroot_deploy_tree_opts.rs [new file with mode: 0644]
rust-bindings/rust/sys/src/auto/versions.txt

index a8ca3fb59e52551fdd4767c43e5f5d5465ed1d6c..0cbdbb02d333885bd8e920af95ce7cec52d27d3e 100644 (file)
@@ -88,6 +88,7 @@ manual = [
     "OSTree.RepoCheckoutAtOptions",
     "OSTree.RepoCheckoutFilter",
     "OSTree.SysrootWriteDeploymentsOpts",
+    "OSTree.SysrootDeployTreeOpts",
 ]
 
 ignore = [
@@ -208,6 +209,18 @@ status = "generate"
 [[object]]
 name = "OSTree.Sysroot"
 status = "generate"
+    [[object.function]]
+    name = "deploy_tree_with_options"
+    [[object.function.parameter]]
+    name = "opts"
+    const = true
+
+    [[object.function]]
+    name = "stage_tree_with_options"
+    [[object.function.parameter]]
+    name = "opts"
+    const = true
+
     [[object.function]]
     name = "write_deployments_with_options"
     [[object.function.parameter]]
index b066af07444d73a2289af87fe14fd0fd557d3cea..0326df9d6d15b509236732b9cbad070d2da55a72 100644 (file)
@@ -30,6 +30,8 @@ use Deployment;
 #[cfg(any(feature = "v2016_4", feature = "dox"))]
 use DeploymentUnlockedState;
 use Repo;
+#[cfg(any(feature = "v2020_7", feature = "dox"))]
+use SysrootDeployTreeOpts;
 use SysrootSimpleWriteDeploymentFlags;
 #[cfg(any(feature = "v2017_4", feature = "dox"))]
 use SysrootWriteDeploymentsOpts;
@@ -78,10 +80,15 @@ impl Sysroot {
         }
     }
 
-    //#[cfg(any(feature = "v2020_7", feature = "dox"))]
-    //pub fn deploy_tree_with_options<P: IsA<gio::Cancellable>>(&self, osname: Option<&str>, revision: &str, origin: Option<&glib::KeyFile>, provided_merge_deployment: Option<&Deployment>, opts: /*Ignored*/Option<&mut SysrootDeployTreeOpts>, cancellable: Option<&P>) -> Result<Deployment, glib::Error> {
-    //    unsafe { TODO: call ostree_sys:ostree_sysroot_deploy_tree_with_options() }
-    //}
+    #[cfg(any(feature = "v2020_7", feature = "dox"))]
+    pub fn deploy_tree_with_options<P: IsA<gio::Cancellable>>(&self, osname: Option<&str>, revision: &str, origin: Option<&glib::KeyFile>, provided_merge_deployment: Option<&Deployment>, opts: Option<&SysrootDeployTreeOpts>, cancellable: Option<&P>) -> Result<Deployment, glib::Error> {
+        unsafe {
+            let mut out_new_deployment = ptr::null_mut();
+            let mut error = ptr::null_mut();
+            let _ = ostree_sys::ostree_sysroot_deploy_tree_with_options(self.to_glib_none().0, osname.to_glib_none().0, revision.to_glib_none().0, origin.to_glib_none().0, provided_merge_deployment.to_glib_none().0, mut_override(opts.to_glib_none().0), &mut out_new_deployment, cancellable.map(|p| p.as_ref()).to_glib_none().0, &mut error);
+            if error.is_null() { Ok(from_glib_full(out_new_deployment)) } else { Err(from_glib_full(error)) }
+        }
+    }
 
     pub fn deployment_set_kargs<P: IsA<gio::Cancellable>>(&self, deployment: &Deployment, new_kargs: &[&str], cancellable: Option<&P>) -> Result<(), glib::Error> {
         unsafe {
@@ -344,10 +351,15 @@ impl Sysroot {
         }
     }
 
-    //#[cfg(any(feature = "v2020_7", feature = "dox"))]
-    //pub fn stage_tree_with_options<P: IsA<gio::Cancellable>>(&self, osname: Option<&str>, revision: &str, origin: Option<&glib::KeyFile>, merge_deployment: Option<&Deployment>, opts: /*Ignored*/&mut SysrootDeployTreeOpts, cancellable: Option<&P>) -> Result<Deployment, glib::Error> {
-    //    unsafe { TODO: call ostree_sys:ostree_sysroot_stage_tree_with_options() }
-    //}
+    #[cfg(any(feature = "v2020_7", feature = "dox"))]
+    pub fn stage_tree_with_options<P: IsA<gio::Cancellable>>(&self, osname: Option<&str>, revision: &str, origin: Option<&glib::KeyFile>, merge_deployment: Option<&Deployment>, opts: &SysrootDeployTreeOpts, cancellable: Option<&P>) -> Result<Deployment, glib::Error> {
+        unsafe {
+            let mut out_new_deployment = ptr::null_mut();
+            let mut error = ptr::null_mut();
+            let _ = ostree_sys::ostree_sysroot_stage_tree_with_options(self.to_glib_none().0, osname.to_glib_none().0, revision.to_glib_none().0, origin.to_glib_none().0, merge_deployment.to_glib_none().0, mut_override(opts.to_glib_none().0), &mut out_new_deployment, cancellable.map(|p| p.as_ref()).to_glib_none().0, &mut error);
+            if error.is_null() { Ok(from_glib_full(out_new_deployment)) } else { Err(from_glib_full(error)) }
+        }
+    }
 
     pub fn try_lock(&self) -> Result<bool, glib::Error> {
         unsafe {
index ca6fe28197f4fcf0cc68ed3cdc2a2cccb7ebe3c8..a7300e77258e1e7d7f12fc93dceadd6b30ad2316 100644 (file)
@@ -1,2 +1,2 @@
 Generated by gir (https://github.com/gtk-rs/gir @ 2d1ffab1)
-from gir-files (https://github.com/gtk-rs/gir-files @ 28a5895+)
+from gir-files (https://github.com/gtk-rs/gir-files @ 2bdb1c1)
index 17635ead15a0c44b52dcf7f3be47c7e683eecc2e..78352506ffd999c068afb7721bb993207e9f184b 100644 (file)
@@ -60,6 +60,10 @@ pub use crate::commit_sizes_entry::*;
 mod sysroot_write_deployments_opts;
 #[cfg(any(feature = "v2017_4", feature = "dox"))]
 pub use crate::sysroot_write_deployments_opts::*;
+#[cfg(any(feature = "v2020_7", feature = "dox"))]
+mod sysroot_deploy_tree_opts;
+#[cfg(any(feature = "v2020_7", feature = "dox"))]
+pub use crate::sysroot_deploy_tree_opts::SysrootDeployTreeOpts;
 
 // tests
 #[cfg(test)]
diff --git a/rust-bindings/rust/src/sysroot_deploy_tree_opts.rs b/rust-bindings/rust/src/sysroot_deploy_tree_opts.rs
new file mode 100644 (file)
index 0000000..040ab63
--- /dev/null
@@ -0,0 +1,98 @@
+use glib::translate::*;
+use libc::c_char;
+use ostree_sys::OstreeSysrootDeployTreeOpts;
+
+pub struct SysrootDeployTreeOpts<'a> {
+    pub override_kernel_argv: Option<&'a [&'a str]>,
+    pub overlay_initrds: Option<&'a [&'a str]>,
+}
+
+impl<'a> Default for SysrootDeployTreeOpts<'a> {
+    fn default() -> Self {
+        SysrootDeployTreeOpts {
+            override_kernel_argv: None,
+            overlay_initrds: None,
+        }
+    }
+}
+
+type OptionStrSliceStorage<'a> =
+    <Option<&'a [&'a str]> as ToGlibPtr<'a, *mut *mut c_char>>::Storage;
+
+impl<'a, 'b: 'a> ToGlibPtr<'a, *const OstreeSysrootDeployTreeOpts> for SysrootDeployTreeOpts<'b> {
+    type Storage = (
+        Box<OstreeSysrootDeployTreeOpts>,
+        OptionStrSliceStorage<'a>,
+        OptionStrSliceStorage<'a>,
+    );
+
+    fn to_glib_none(&'a self) -> Stash<*const OstreeSysrootDeployTreeOpts, Self> {
+        // Creating this struct from zeroed memory is fine since it's `repr(C)` and only contains
+        // primitive types. Zeroing it ensures we handle the unused bytes correctly.
+        // The struct needs to be boxed so the pointer we return remains valid even as the Stash is
+        // moved around.
+        let mut options = Box::new(unsafe { std::mem::zeroed::<OstreeSysrootDeployTreeOpts>() });
+        let override_kernel_argv = self.override_kernel_argv.to_glib_none();
+        let overlay_initrds = self.overlay_initrds.to_glib_none();
+        options.override_kernel_argv = override_kernel_argv.0;
+        options.overlay_initrds = overlay_initrds.0;
+        Stash(
+            options.as_ref(),
+            (options, override_kernel_argv.1, overlay_initrds.1),
+        )
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use std::{ffi::CStr, ptr::null_mut};
+
+    unsafe fn ptr_array_as_slice<'a, T>(ptr: *mut *mut T) -> &'a [*mut T] {
+        let mut len = 0;
+        while !(*ptr.offset(len)).is_null() {
+            len += 1;
+        }
+        std::slice::from_raw_parts(ptr, len as usize)
+    }
+
+    unsafe fn str_ptr_array_to_vec<'a>(ptr: *mut *mut c_char) -> Vec<&'a str> {
+        ptr_array_to_slice(ptr)
+            .iter()
+            .map(|x| CStr::from_ptr(*x).to_str().unwrap())
+            .collect()
+    }
+
+    #[test]
+    fn should_convert_default_options() {
+        let options = SysrootDeployTreeOpts::default();
+        let stash = options.to_glib_none();
+        let ptr = stash.0;
+        unsafe {
+            assert_eq!((*ptr).override_kernel_argv, null_mut());
+            assert_eq!((*ptr).overlay_initrds, null_mut());
+        }
+    }
+
+    #[test]
+    fn should_convert_non_default_options() {
+        let override_kernel_argv = vec!["quiet", "splash", "ro"];
+        let overlay_initrds = vec!["overlay1", "overlay2"];
+        let options = SysrootDeployTreeOpts {
+            override_kernel_argv: Some(&override_kernel_argv),
+            overlay_initrds: Some(&overlay_initrds),
+        };
+        let stash = options.to_glib_none();
+        let ptr = stash.0;
+        unsafe {
+            assert_eq!(
+                str_ptr_array_to_vec((*ptr).override_kernel_argv),
+                vec!["quiet", "splash", "ro"]
+            );
+            assert_eq!(
+                str_ptr_array_to_vec((*ptr).overlay_initrds),
+                vec!["overlay1", "overlay2"]
+            );
+        }
+    }
+}
index ca6fe28197f4fcf0cc68ed3cdc2a2cccb7ebe3c8..a7300e77258e1e7d7f12fc93dceadd6b30ad2316 100644 (file)
@@ -1,2 +1,2 @@
 Generated by gir (https://github.com/gtk-rs/gir @ 2d1ffab1)
-from gir-files (https://github.com/gtk-rs/gir-files @ 28a5895+)
+from gir-files (https://github.com/gtk-rs/gir-files @ 2bdb1c1)